package view;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

import model.Carta;
import model.Jogador;
import model.Mensagem;
import model.Retorno;
import controller.Controle;

public class TelaJogo extends JPanel implements Retorno, Runnable {

	private static final long serialVersionUID = 1L;
	private Controle controle;
	private AttHandler attHandler;
	private ImageIcon inverso;
	private JLabel suaCarta;
	private JLabel cartaOponente;
	private JLabel lblForca;
	private JLabel lblVelocidade;
	private JLabel lblHabilidade;
	private JLabel lblEquipamento;
	private JLabel lblInteligencia;
	private JProgressBar suaProgressBar;	
	private JProgressBar progressBarOponente;
	private JButton btnSair;
	private JLabel lblInfo;
	private boolean verificar = true;
	private int count;
	
	public TelaJogo(Controle controle) {
		setLayout(null);
		setSize(800,600);
		
		this.controle	= controle;
		this.inverso	= getImagem("cartas/inverso.jpg");
		this.attHandler = new AttHandler();
		
		
		lblForca = new JLabel();
		lblForca.setBounds(118, 343, 239, 26);
		add(lblForca);
		
		lblVelocidade = new JLabel();
		lblVelocidade.setBounds(128, 369, 229, 26);
		add(lblVelocidade);
		
		lblHabilidade = new JLabel();
		lblHabilidade.setBounds(138, 395, 219, 26);
		add(lblHabilidade);
		
		lblEquipamento = new JLabel();
		lblEquipamento.setBounds(152, 421, 205, 26);
		add(lblEquipamento);
		
		lblInteligencia = new JLabel();
		lblInteligencia.setBounds(164, 447, 193, 26);
		add(lblInteligencia);
		
		suaCarta = new JLabel();
		suaCarta.setBounds(69, 112, 296, 400);
		suaCarta.setIcon(inverso);
		add(suaCarta);
		
		cartaOponente = new JLabel();
		cartaOponente.setBounds(434, 112, 296, 400);
		cartaOponente.setIcon(inverso);
		add(cartaOponente);
		
		suaProgressBar = new JProgressBar();
		suaProgressBar.setValue(15);
		suaProgressBar.setMaximum(30);
		suaProgressBar.setStringPainted(true);
		suaProgressBar.setString("Total de cartas");
		suaProgressBar.setBounds(143, 524, 148, 21);
		add(suaProgressBar);
		
		progressBarOponente = new JProgressBar();
		progressBarOponente.setValue(15);
		progressBarOponente.setMaximum(30);
		progressBarOponente.setStringPainted(true);
		progressBarOponente.setString("Total de cartas");
		progressBarOponente.setBounds(508, 524, 148, 21);
		add(progressBarOponente);
		
		JLabel lblSuaCarta = new JLabel("Sua Carta");
		lblSuaCarta.setFont(new Font("Calibri", Font.BOLD, 18));
		lblSuaCarta.setHorizontalAlignment(SwingConstants.CENTER);
		lblSuaCarta.setBounds(69, 84, 296, 16);
		add(lblSuaCarta);
		
		JLabel lblCartaDoOponente = new JLabel("Carta do Oponente");
		lblCartaDoOponente.setHorizontalAlignment(SwingConstants.CENTER);
		lblCartaDoOponente.setFont(new Font("Calibri", Font.BOLD, 18));
		lblCartaDoOponente.setBounds(434, 84, 296, 16);
		add(lblCartaDoOponente);
		
		lblInfo = new JLabel("Jogar!");
		lblInfo.setFont(new Font("Calibri", Font.BOLD, 26));
		lblInfo.setHorizontalAlignment(SwingConstants.CENTER);
		lblInfo.setBounds(12, 12, 776, 60);
		add(lblInfo);
		
		btnSair = new JButton("Sair");
		btnSair.setFont(new Font("Calibri", Font.PLAIN, 14));
		btnSair.setBounds(12, 562, 98, 26);
		btnSair.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				voltarLista();
			}
		});
		add(btnSair);
		
		try {
			this.controle.solicitarCarta(this);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Thread verificador = new Thread(this);
		verificador.start();
	}
	
	private ImageIcon getImagem(String imagemNome) {
		try {
//			BufferedImage imagem = ImageIO.read(new File(
//					this.getClass().getResource("../images/"+imagemNome).getPath()));
			
			BufferedImage imagem = ImageIO.read(getClass().getResource("/images/"+imagemNome));
			
			Image imagemMenor = imagem.getScaledInstance(296, 400, Image.SCALE_AREA_AVERAGING+Image.SCALE_SMOOTH);
			return new ImageIcon(imagemMenor);
		} catch (IOException e) {
			e.printStackTrace();
		}		
		return null;
	}
	
	private class AttHandler extends MouseAdapter {
		@Override
		public void mouseClicked(MouseEvent e) {
			try {
				if(e.getSource() == lblForca) {
					controle.escolherAtt("forca", TelaJogo.this);
				} else if(e.getSource() == lblVelocidade) {
					controle.escolherAtt("velocidade", TelaJogo.this);
				} else if(e.getSource() == lblHabilidade) {
					controle.escolherAtt("habilidade", TelaJogo.this);
				} else if(e.getSource() == lblEquipamento) {
					controle.escolherAtt("equipamento", TelaJogo.this);
				} else if(e.getSource() == lblInteligencia) {
					controle.escolherAtt("inteligencia", TelaJogo.this);
				}
				removerEventos();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			Object object = e.getSource();
			if(object.getClass().getSimpleName().equalsIgnoreCase("JLabel")) {
				JLabel label = (JLabel) object;
				label.setBorder(new LineBorder(new Color(0, 196, 223), 3));
			}
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			Object object = e.getSource();
			if(object.getClass().getSimpleName().equalsIgnoreCase("JLabel")) {
				JLabel label = (JLabel) object;
				label.setBorder(null);
			}
		}
		
		@Override
		public void mousePressed(MouseEvent e) {
			Object object = e.getSource();
			if(object.getClass().getSimpleName().equalsIgnoreCase("JLabel")) {
				JLabel label = (JLabel) object;
				label.setBorder(new LineBorder(new Color(0, 103, 132), 3));
			}			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			Object object = e.getSource();
			if(object.getClass().getSimpleName().equalsIgnoreCase("JLabel")) {
				JLabel label = (JLabel) object;
				label.setBorder(new LineBorder(new Color(0, 196, 223), 3));
			}			
		}
	}
	
	private void addEventos() {
		JLabel[] labels = {lblForca,lblVelocidade,lblHabilidade,lblEquipamento,lblInteligencia};
		for(JLabel j : labels){
			j.addMouseListener(attHandler);
			
		}
	}
	
	private void removerEventos() {
		JLabel[] labels = {lblForca,lblVelocidade,lblHabilidade,lblEquipamento,lblInteligencia};
		for(JLabel label : labels){
			label.removeMouseListener(attHandler);
			label.setBorder(null);
		}
	}

	@Override
	public void retornar(Object object) throws ClassCastException {
		this.count = 0;
		
		if(!object.getClass().getSimpleName().equalsIgnoreCase("Mensagem"))return;
		Mensagem msg = (Mensagem) object;
		
		//Primeiro, remove os eventos dos atributos
		this.removerEventos();
		
		if(msg.getAssunto().equalsIgnoreCase("vitoria")) {
			Jogador perdedor = (Jogador) msg.getObjeto();
			lblInfo.setText("Voc� venceu " + perdedor.getNome());
			this.getParent().repaint();
			return;
		} else if(msg.getAssunto().equalsIgnoreCase("derrota")) {
			Jogador vencedor = (Jogador) msg.getObjeto();
			lblInfo.setText("Voc� perdeu para " + vencedor.getNome());
			this.getParent().repaint();
			return;
		}
		
		if(msg.getObjeto()!=null && !msg.getObjeto().getClass().getSimpleName().equalsIgnoreCase("Carta")) return;
		Carta carta = (Carta) msg.getObjeto();		
		
		System.out.println("Menssagem recebida, assunto: " + msg.getAssunto());
		if(msg.getAssunto().equalsIgnoreCase("escolha")) {
			this.suaCarta.setIcon(getImagem(carta.getImagem()));
			this.cartaOponente.setIcon(inverso);
			//Adiciona os eventos
			this.addEventos();
			this.lblInfo.setText("Informe um atributo");
		} else if(msg.getAssunto().equalsIgnoreCase("espere")) {
			this.suaCarta.setIcon(inverso);
			this.cartaOponente.setIcon(getImagem(carta.getImagem()));
			try {
				this.controle.escolherAtt("ver resultado", this);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.lblInfo.setText("Aguarde a jogada do seu advers�rio");
		} else {
			
			this.progressBarOponente.setValue(msg.getOponenteQtd());
			this.suaProgressBar.setValue(msg.getSuaQtd());			
			
			if(msg.getAssunto().equalsIgnoreCase("perdeu")) {
				this.cartaOponente.setIcon(getImagem(carta.getImagem()));
				this.lblInfo.setText("Falhou");				
			} else if(msg.getAssunto().equalsIgnoreCase("venceu")) {
				this.cartaOponente.setIcon(getImagem(carta.getImagem()));
				this.lblInfo.setText("Conseguiu");	
			} else if(msg.getAssunto().equalsIgnoreCase("empatou")) {
				this.cartaOponente.setIcon(getImagem(carta.getImagem()));
				this.lblInfo.setText("Empate");
			} else {
				
				this.suaCarta.setIcon(getImagem(carta.getImagem()));
				
				if(msg.getAssunto().equalsIgnoreCase("forca")) {
					this.lblInfo.setText("O advers�rio usou a for�a");
				} else if (msg.getAssunto().equalsIgnoreCase("velocidade")) {
					this.lblInfo.setText("O advers�rio usou a velocidade");
				} else if (msg.getAssunto().equalsIgnoreCase("habilidade")) {
					this.lblInfo.setText("O advers�rio usou a habilidade");
				} else if (msg.getAssunto().equalsIgnoreCase("equipamento")) {
					this.lblInfo.setText("O advers�rio usou equipamento");
				} else if (msg.getAssunto().equalsIgnoreCase("inteligencia")) {
					this.lblInfo.setText("O advers�rio usou a intelig�ncia");
				}
			}
			
			try {
				this.controle.solicitarCarta(this);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.getParent().repaint();
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		count = 0;
		while(verificar){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			count++;
			if(!this.controle.isGameConnected() || count>30){
				voltarLista();
				JOptionPane.showMessageDialog(this, "Problemas na conex�o com jogador");
			}			
		}
	}
	
	public void voltarLista(){
		try {
			verificar = false;
			TelaJogo.this.controle.encerrarRequisicao();
			Container parent = TelaJogo.this.getParent();
			parent.remove(TelaJogo.this);
			parent.add(new TelaListaJogadores(TelaJogo.this.controle));
			parent.validate();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
}
